#include "spreadsheetmodel.h"

SpreadsheetModel::SpreadsheetModel(int rows, int columns, QObject *parent)
    : QStandardItemModel(rows, columns, parent)
    ,undoredoprogress(false),//初始化撤销标记
    m_evaluator(this)//初始化公式计算器
{
    // 列标题（A, B, C...）
    for (int col = 0; col < columnCount(); ++col) {
        setHeaderData(col, Qt::Horizontal, QChar('A' + col % 26));
    }
    //初始化命令栈
    m_undoStack=new QUndoStack(this);
}
SpreadsheetModel::~SpreadsheetModel()
{
    delete(this);
}

/*重写函数*/
// 设置表头样式函数
QVariant SpreadsheetModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    // 水平表头处理
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
        QString header;
        int n = section;
        do {
            header.prepend(QChar('A' + n % 26));
            n = n / 26 - 1;
        } while (n >= 0);
        return header;
    }
    // 默认情况处理
    return QStandardItemModel::headerData(section, orientation, role);
}

//设置数据项函数
bool SpreadsheetModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid()) {
        qDebug()<<"无效索引";
        return false;
    }
    // 清理数据
    QString text = value.toString().trimmed();
    if (text.isEmpty() || value.toString().endsWith('\n') || value.toString().endsWith('\r')) {
        text.clear();
    }

    QVariant newValue(text);
    QVariant oldValue = data(index, role);
    if (oldValue == newValue) {
        return true;
    }
    // 如果是撤销/重做操作，直接设置数据
    if (undoredoprogress) {
        return QStandardItemModel::setData(index, newValue, role);
    }

    // 阻塞信号防止递归触发
    bool wasBlocked = blockSignals(true);
    bool success = false;
    // 分角色处理
    if (role == Qt::EditRole) {
        // 保存原始数据（公式或值）
        success = QStandardItemModel::setData(index, newValue, role);

         // 如果是公式，触发重新计算
        if (value.toString().startsWith("=")) {
            //调用方法计算
            QVariant result = calculateFormula(value.toString(),index);
            QStandardItemModel::setData(index, result, Qt::DisplayRole);
        } else {
            // 普通值同步到DisplayRole
            QStandardItemModel::setData(index, value, Qt::DisplayRole);
        }

        // 恢复信号
        blockSignals(wasBlocked);
        // 发出信号通知外部处理 撤回重做
        emit dataChangedEx(index, oldValue, newValue);

    }
    else if (role == Qt::DisplayRole) {
        // 直接保存显示值（计算结果或普通数据）
        success = QStandardItemModel::setData(index, newValue, role);
        // 恢复信号并触发标准 dataChanged
        blockSignals(wasBlocked);
    }
    else {
        // 其他角色（如字体、颜色等）
        success = QStandardItemModel::setData(index, newValue, role);
        // 恢复信号并触发标准 dataChanged
        blockSignals(wasBlocked);
    }

    if (success) {
        emit dataChanged(index, index, {role});
    }
    return success;
}

//读取数据函数
QVariant SpreadsheetModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= rowCount() || index.column() >= columnCount()) {
        return QVariant();
    }
    // 1. 直接返回 EditRole（原始公式，不计算）
    if (role == Qt::EditRole) {
        // qDebug()<<"获取编辑值："<<QStandardItemModel::data(index, Qt::EditRole);
        return QStandardItemModel::data(index, Qt::EditRole);
    }
    // 2. 处理 DisplayRole（计算后的值）
    if (role == Qt::DisplayRole) {
        // 直接从父类获取DisplayRole的值
        QVariant editValue =QStandardItemModel::data(index, Qt::EditRole);
        if (editValue.toString().startsWith("=")) {
            return calculateFormula(editValue.toString(),index); // 只在这里计算
        }
        return editValue; // 普通值直接返回
    }
    // 其他角色（如文本对齐、背景色等）交给父类处理

    return QStandardItemModel::data(index, role);
}

/* 序列化操作符实现*/
//  将模型导出至数据流 out << model1
QDataStream &operator<<(QDataStream &out, const SpreadsheetModel &model)
{
    // 写入行数和列数、
    // 先写入模型的行数，再写入列数（顺序必须固定，反序列化时需按相同顺序读取）。
    out << model.rowCount() << model.columnCount();

    // 写入所有单元格数据
    for (int row = 0; row < model.rowCount(); ++row) {
        for (int col = 0; col < model.columnCount(); ++col) {
            QModelIndex index = model.index(row, col);
            QVariant cellData = model.data(index,Qt::DisplayRole);
            // 写入单元格数据
            out << cellData;
        }
    }
    return out;
}
// 从数据流中导入模型 in >> model1
QDataStream &operator>>(QDataStream &in, SpreadsheetModel &model)
{
    int rows, cols;
    // 读取行数和列数
    in >> rows >> cols;
    // 调整模型大小
    model.setRowCount(rows);
    model.setColumnCount(cols);

    for (int row = 0; row < rows; ++row) {
        for (int col = 0; col < cols; ++col) {
            QModelIndex index = model.index(row, col);
            // 读取单元格数据
            QVariant data;
            in >> data;
            model.setData(index, data);
        }
    }
    // 支持链式调用（如 in >> model1 >> model2）
    return in;
}

/*删除行列操作*/
//获取行数据
QVariantList SpreadsheetModel::getRowData(int row)
{
    QVariantList data;
    for (int col = 0; col < columnCount(); col++) {
        data.append(index(row, col).data());
    }
    return data;
}
//获取列数据
QVariantList SpreadsheetModel::getColData(int col)
{
    QVariantList data;
    for (int row = 0; row< rowCount(); row++) {
        data.append(index(row, col).data());
    }
    return data;
}
//恢复行数据
void SpreadsheetModel::setRowData(int row, const QVariantList &data) {
    for (int col = 0; col < data.size(); col++) {
        setData(index(row, col), data[col],Qt::EditRole);
    }
}
//恢复列数据
void SpreadsheetModel::setColData(int col, const QVariantList &data) {
    for (int row = 0; row < data.size(); row++) {
        setData(index(row, col), data[row],Qt::EditRole);
    }
}

/*命令栈操作*/
//设置命令栈
void SpreadsheetModel::setUndoStack(QUndoStack *undoStack)
{
    m_undoStack = undoStack;
}
// 获取命令栈
QUndoStack *SpreadsheetModel::undoStack() const
{
    return m_undoStack;
}
//标记开始撤销重做
void SpreadsheetModel::beginUndoRedo()
{
    undoredoprogress = true;
}
//标记结束撤销重做
void SpreadsheetModel::endUndoRedo()
{
    undoredoprogress = false;
    // 批量通知数据变更
    emit dataChanged(index(0, 0), index(rowCount()-1, columnCount()-1));
}

/*排序操作*/
//比较两个QVariant
bool SpreadsheetModel::compareVariants(const QVariant &v1, const QVariant &v2, bool caseSensitive, Qt::SortOrder order)
{
    // 判断是否为空值（空字符串、无效 QVariant 等都视为空）
    bool isV1Empty = !v1.isValid() || v1.toString().trimmed().isEmpty();
    bool isV2Empty = !v2.isValid() || v2.toString().trimmed().isEmpty();
    // 如果两个都为空，保持相对顺序（不交换）
    if (isV1Empty && isV2Empty) {
        return false;
    }
    // 如果 v1 为空，v2 非空，则 v1 应该排在后面（无论升序还是降序）
    if (isV1Empty) {
        return false;
    }
    // 如果 v2 为空，v1 非空，则 v2 应该排在后面（无论升序还是降序）
    if (isV2Empty) {
        return true;
    }

    // 尝试转换为数字（如果都是数字，按数值比较）
    bool ok1, ok2;

    double num1 = v1.toDouble(&ok1);
    double num2 = v2.toDouble(&ok2);
    if (ok1 && ok2) {  // 如果两个都是数字
        return order == Qt::AscendingOrder ? num1 < num2 : num1 > num2;
    }

    // 字符串比较
    QString s1 = v1.toString().trimmed();
    QString s2 = v2.toString().trimmed();
    if (!caseSensitive) {
        s1 = s1.toLower();
        s2 = s2.toLower();
    }

    return order == Qt::AscendingOrder ?
               s1 < s2 : s1 > s2;
}
// 获取当前所有数据
QVector<QVector<QVariant> > SpreadsheetModel::getAllData() const
{
    QVector<QVector<QVariant>> data;
    for (int r = 0; r < rowCount(); ++r) {
        QVariantList row;
        for (int c = 0; c < columnCount(); ++c) {
            row.append(index(r, c).data());
        }
        data.append(row.toVector());
    }
    return data;
}
// 批量设置数据
void SpreadsheetModel::setAllData(const QVector<QVector<QVariant> > &data)
{
    // 调整模型大小（不触发重置）
    if (rowCount() != data.size()) {
        if (rowCount() < data.size()) {
            insertRows(rowCount(), data.size() - rowCount());
        } else {
            removeRows(data.size(), rowCount() - data.size());
        }
    }
    if (!data.isEmpty() && columnCount() != data[0].size()) {
        if (columnCount() < data[0].size()) {
            insertColumns(columnCount(), data[0].size() - columnCount());
        } else {
            removeColumns(data[0].size(), columnCount() - data[0].size());
        }
    }
    // 逐项更新数据
    for (int r = 0; r < data.size(); ++r) {
        for (int c = 0; c < data[r].size(); ++c) {
            QModelIndex idx = index(r, c);
            QStandardItemModel::setData(idx, data[r][c], Qt::EditRole);
        }
    }
}
// 按列排序
void SpreadsheetModel::sortColumn(int column, Qt::SortOrder order, bool caseSensitive)
{
    // 如果 column 是负数或超出列数范围，直接返回，避免越界访问
    if (column < 0 || column >= columnCount()){
        qDebug() << "Error: Invalid column index" << column;
        return;
    }

    //获取所有行的数据 整个表格连带排序
    QVector<QVector<QVariant>> allRows;
    for (int row = 0; row < rowCount(); row++) {
        QVariantList rowData = getRowData(row);
        // 确保每一行的列数足够，不足则填充 Invalid
        while (rowData.size() <= column) {
            rowData.append(QVariant());
        }

        allRows.append(rowData.toVector());//  getRowData() 返回 QVariantList
    }

    // 使用lambda表达式作为比较函数
    std::stable_sort(allRows.begin(), allRows.end(),
                     [column, order, caseSensitive](const QVector<QVariant> &row1, const QVector<QVariant> &row2) {
                         // 确保 column 不越界
                         const QVariant &v1 = (column < row1.size()) ? row1[column] : QVariant();
                         const QVariant &v2 = (column < row2.size()) ? row2[column] : QVariant();
                         return compareVariants(v1, v2, caseSensitive, order);
                     });

    // 更新数据
    for (int row = 0; row < allRows.size(); row++) {
        setRowData(row, QVariantList::fromVector(allRows[row]));
    }
}
// 按行排序
void SpreadsheetModel::sortRow(int row, Qt::SortOrder order, bool caseSensitive)
{
    // 如果 row 是负数或超出行数范围，直接返回，避免越界访问
    if (row < 0 || row >= rowCount()) {
        qDebug() << "Error: Invalid Row index" << row;
        return;
    }

    // 获取所有列的数据
    QVector<QVector<QVariant>> allColumns;
    for (int col = 0; col < columnCount(); col++) {
        QVariantList colData = getColData(col);
        while(colData.size()<=row){
            colData.append(QVariant());
        }
        allColumns.append(colData.toVector());
    }

    //使用 lambda 表达式作为比较函数，按指定行的值对列排序
    std::stable_sort(allColumns.begin(), allColumns.end(),
                     [row, order, caseSensitive](const QVector<QVariant> &col1, const QVector<QVariant> &col2) {
                         // 确保 column 不越界
                         const QVariant &v1 = (row < col1.size()) ? col1[row] : QVariant();
                         const QVariant &v2 = (row< col2.size()) ? col2[row] : QVariant();
                         return compareVariants(v1, v2, caseSensitive, order);
                     });

    // 更新数据
    for (int col = 0;col< allColumns.size(); col++) {
        setColData(col, QVariantList::fromVector(allColumns[col]));
    }

}

/*公式计算*/
//计算公式值
QVariant SpreadsheetModel::calculateFormula(const QString &formula, const QModelIndex &index)const
{
    QVariant result = m_evaluator.evaluate(formula,index.row(),index.column());
    return result ;
}

